<!DOCTYPE html>
<html>
<head>
    <title>Relativity Diagram</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        canvas {
            border: 1px solid #ccc;
            background-color: #fff;
        }
    </style>
</head>
<body>
    <canvas id="relativityCanvas" width="550" height="350"></canvas>
    <script>
        const canvas = document.getElementById('relativityCanvas');
        const ctx = canvas.getContext('2d');

        // --- Style and Helper Functions ---

        // Helper function to draw a line with an arrowhead
        function drawArrow(fromx, fromy, tox, toy) {
            const headlen = 10; // length of head in pixels
            const dx = tox - fromx;
            const dy = toy - fromy;
            const angle = Math.atan2(dy, dx);
            
            // Main line
            ctx.beginPath();
            ctx.moveTo(fromx, fromy);
            ctx.lineTo(tox, toy);
            ctx.stroke();
            
            // Arrowhead
            ctx.beginPath();
            ctx.moveTo(tox, toy);
            ctx.lineTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6));
            ctx.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6));
            ctx.closePath();
            ctx.save();
            ctx.fillStyle = ctx.strokeStyle;
            ctx.fill();
            ctx.restore();
        }

        // --- Define Coordinates ---
        const origin = { x: 60, y: 300 };
        const xAxisEnd = { x: 520, y: 300 };
        const yAxisEnd = { x: 60, y: 30 };
        const sourcePos = { x: 150, y: 100 };
        const observerPos = { x: 420, y: 240 };
        const velEndPoint = { x: 300, y: 100 };

        // --- Drawing ---

        ctx.clearRect(0, 0, canvas.width, canvas.height);
        
        // 1. Draw Coordinate System
        ctx.strokeStyle = 'black';
        ctx.lineWidth = 1.5;
        drawArrow(origin.x, origin.y, xAxisEnd.x, origin.y); // x-axis
        drawArrow(origin.x, origin.y, origin.x, yAxisEnd.y); // y-axis

        // 2. Labels for Axes, Origin, and Frame
        ctx.fillStyle = 'black';
        ctx.font = 'italic 22px "Times New Roman"';
        ctx.fillText('y', yAxisEnd.x - 20, yAxisEnd.y + 10);
        ctx.fillText('x', xAxisEnd.x, xAxisEnd.y + 20);
        ctx.fillText('O', origin.x - 25, origin.y + 20);
        
        ctx.font = '24px "SimSun", "Songti SC"';
        ctx.fillText('S系', origin.x + 30, origin.y - 30);

        // 3. Draw Light Source and Observer
        // Light Source Point
        ctx.beginPath();
        ctx.arc(sourcePos.x, sourcePos.y, 5, 0, 2 * Math.PI);
        ctx.fill();
        
        // Observer Point P
        ctx.beginPath();
        ctx.arc(observerPos.x, observerPos.y, 5, 0, 2 * Math.PI);
        ctx.fill();

        // 4. Draw Velocity Vector
        ctx.lineWidth = 2;
        drawArrow(sourcePos.x, sourcePos.y, velEndPoint.x, velEndPoint.y);

        // 5. Draw Line of Sight (dashed line)
        ctx.save();
        ctx.beginPath();
        ctx.setLineDash([6, 4]);
        ctx.lineWidth = 1.5;
        ctx.moveTo(sourcePos.x, sourcePos.y);
        ctx.lineTo(observerPos.x, observerPos.y);
        ctx.stroke();
        ctx.restore();

        // 6. Draw Angle θ
        const arcRadius = 45;
        const angleEnd = Math.atan2(observerPos.y - sourcePos.y, observerPos.x - sourcePos.x);
        ctx.beginPath();
        ctx.lineWidth = 1;
        ctx.arc(sourcePos.x, sourcePos.y, arcRadius, 0, angleEnd);
        ctx.stroke();

        // 7. Add Text Labels for objects
        // "点光源" (Point Light Source)
        ctx.font = '28px "SimSun", "Songti SC"';
        ctx.textAlign = 'center';
        ctx.fillText('点光源', sourcePos.x, sourcePos.y - 25);
        
        // "观察者" (Observer) and P
        ctx.textAlign = 'left';
        ctx.fillText('观察者', observerPos.x + 15, observerPos.y);
        ctx.font = 'italic 24px "Times New Roman"';
        ctx.fillText('P', observerPos.x - 25, observerPos.y + 5);
        
        // Velocity Label 'v'
        ctx.fillText('v', velEndPoint.x + 10, velEndPoint.y + 8);

        // Angle Label 'θ'
        const angleMid = angleEnd / 2;
        const thetaLabelPos = {
            x: sourcePos.x + (arcRadius + 15) * Math.cos(angleMid),
            y: sourcePos.y + (arcRadius + 15) * Math.sin(angleMid)
        };
        ctx.fillText('θ', thetaLabelPos.x - 5, thetaLabelPos.y + 10);

    </script>
</body>
</html>